package displayboardinfo.entities;

import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

/**
 *  
 * Klasa reprezentująca pojedynczy okres przyjęć gabinetu lekarskiego.
 * Każdy z gabinetów ma stały cykl otwarcia/zamknięcia w każdym z tygodni.
 *
 * @author Artur Jaworski
 */
@Entity
@Table ( name = "Admissions" )
@XmlRootElement
@XmlType(propOrder = { "id", "room", "user", "dayOfWeek", "openHour", "closeHour" })
public class Admission {
	@Id
	@Column( name = "id" )
	@GeneratedValue(strategy=GenerationType.AUTO)
	protected long id;
	
	@ManyToOne
	@JoinColumn( name = "id_room", nullable = false )
	protected Room room;
	
	@ManyToOne
	@JoinColumn( name = "id_user", nullable = false )
	protected User user;
	
	@Column( name = "day_of_week", nullable = false )
	protected int dayOfWeek;
	
	@Column( name = "open_hour", nullable = false )
	protected Date openHour;
	
	@Column( name = "close_hour", nullable = false )
	protected Date closeHour;

	/**
	 * Domyślny konstruktor bezargumentowy.
	 */
	public Admission() {
	
	}
	
	/**
	 * Pobranie unikalnego numeru ID okresu przyjęć gabinetu. 
	 * 
	 * @return unikalny numer ID
	 */
	public long getId() {
		return id;
	}

	/**
	 * Ustawienie unikalnego numeru ID okresu przyjęć gabinetu.
	 * Ręczne ustawianie numeru ID powinno być zawsze robione z rozwagą. 
	 * 
	 * @param id unikalny numer ID
	 */
	public void setId(long id) {
		this.id = id;
	}

	/**
	 * Pobranie obiektu gabinetu skojarzonego z okresem przyjęć.
	 * 
	 * @return gabinet skojarzony z okresem przyjęć
	 */
	public Room getRoom() {
		return room;
	}

	/**
	 * Ustawienie obiektu gabinetu skojarzonego z okresem przyjęć.
	 * 
	 * @param room gabinet skojarzony z okresem przyjęć
	 */
	public void setRoom(Room room) {
		this.room = room;
	}

	/**
	 * Pobranie obiektu użytkownika (lekarza) przyjmującego w danym okresie przyjęć
	 * 
	 * @return użytkownik (lekarz) przyjmujący w danym okresie przyjęć
	 */
	public User getUser() {
		return user;
	}

	/**
	 * Ustawienie obiektu użytkownika (lekarza) przyjmującego w danym okresie przyjęć
	 * 
	 * @param user użytkownik (lekarz) przyjmujący w danym okresie przyjęć
	 */
	public void setUser(User user) {
		this.user = user;
	}

	/**
	 * Pobranie dnia tygodnia okresu przyjęć.
	 * 0 - niedziela, 1 - poniedziałek, ... , 6 - sobota
	 * 
	 * @return dzień tygodnia
	 */
	public int getDayOfWeek() {
		return dayOfWeek;
	}

	/**
	 * Ustawienie dnia tygodnia okresu przyjęć.
	 * 0 - niedziela, 1 - poniedziałek, ... , 6 - sobota
	 * 
	 * @param dayOfWeek dzień tygodnia
	 */
	public void setDayOfWeek(int dayOfWeek) {
		this.dayOfWeek = dayOfWeek;
	}

	/**
	 * Pobranie godziny otwarcia gabinetu
	 * 
	 * @return godzina otwarcia gabinetu
	 */
	public Date getOpenHour() {
		return openHour;
	}

	/**
	 * Ustawienie godziny otwarcia gabinetu
	 * 
	 * @param openHour godzina otwarcia gabinetu
	 */
	public void setOpenHour(Date openHour) {
		this.openHour = openHour;
	}

	/**
	 * Pobranie godziny zamknięcia gabinetu
	 * 
	 * @return godzina zamknięcia gabinetu
	 */
	public Date getCloseHour() {
		return closeHour;
	}

	/**
	 * Ustawienie godziny zamknięcia gabinetu
	 * 
	 * @param closeHour godzina zamknięcia gabinetu
	 */
	public void setCloseHour(Date closeHour) {
		this.closeHour = closeHour;
	}
	
	/**
	 * Konwersja obiektu okresu przyjęć na łatwy do zrozumienia łańcuch znaków.
	 * 
	 * @return sformatowany łańcuch znaków
	 */
	@Override
	public String toString() {
		String text = new String();

		Locale usersLocale = Locale.getDefault();
		DateFormatSymbols dfs = new DateFormatSymbols(usersLocale);
	    String weekdays[] = dfs.getWeekdays();
	    
	    SimpleDateFormat hourFormat = new SimpleDateFormat("HH:mm");
	    
		text += "\nid:" + id + "\n" +
				"dayOfWeek:" + weekdays[dayOfWeek+1] +" [" + dayOfWeek + "]" + "\n" +
				"openHour:" + hourFormat.format(openHour) + "\n" +
				"closeHour:" + hourFormat.format(closeHour);
		if (user != null)
			text += "\nidUser:" + user.getId();
		if (room != null)
				text += "\nidRoom:" + room.getId();
		
		return text;
	}
	
	/**
	 * Sprawdzenie czy podana data mieści się w okresie przyjmowania gabinetu.
	 * 
	 * @param date sprawdzana data
	 * @return czy data mieści się w okresie przyjmowania gabinetu
	 */
	@SuppressWarnings("deprecation")
	public boolean isInDate(Date date){
		if (date.getDay() != dayOfWeek)
			return false;
		
		double startTime = openHour.getHours() + openHour.getMinutes() / 60.0;
		double closeTime = closeHour.getHours() + closeHour.getMinutes() / 60.0;
		double time = date.getHours() + date.getMinutes() / 60.0;
		if (time < startTime || time >= closeTime)
			return false;
		
		return true;
	}
}
